﻿using Application.PermissionService;
using Application.ProductTypeService;
using Application.SupplierService;
using Application.UserService;
using Domain.Entity;
using Domain.Entity.bs;
using Domain.Entity.sys;
using Domain.Entity.zct;
using Domain.IRepository;
using EFCore.Repository;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using OfficeOpenXml;
using System.Linq;

namespace WMSManage.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]//需要鉴权
    public class SupplierController : ControllerBase
    {
        private readonly ISupplierService supplierService;

        public SupplierController(ISupplierService supplierService)
        {
            this.supplierService = supplierService;
        }

        /// <summary>
        /// 查询供应商
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<FenYe<Supplier>> GetSupplier(int CurrentPage, string? sup_code, string? sup_name, int? sup_status, string? sup_industry, string? sup_userName)
        {
            FenYe<Supplier> fenYe = new FenYe<Supplier>()
            {
                CurrentPage = CurrentPage,
            };
            return await supplierService.GetSupplier(fenYe, sup_code, sup_name, sup_status, sup_industry, sup_userName);
        }

        /// <summary>
        /// 添加供应商
        /// </summary>
        /// <param name="addSupplierDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<int> AddSupplier(AddSupplierDto addSupplierDto)
        {
            return await supplierService.AddSupplier(addSupplierDto);
        }


        /// <summary>
        /// 删除供应商
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut] 
        public async Task<IActionResult> DeleteSupplier(int id)
        {
            try
            {
                var result = await supplierService.DeleteSupplier(id);

                // 根据 Repository 返回的 int 结果，返回不同的 HTTP 响应
                return result switch
                {
                    1 => Ok(new { code = 1, message = "供应商删除成功" }),
                    0 => BadRequest(new { code = 0, message = "删除失败：该供应商已被其他单据引用，无法删除" }),
                    -1 => NotFound(new { code = -1, message = "供应商不存在或已被删除" }),
                    _ => StatusCode(500, new { code = -2, message = "服务器内部错误：未知的删除结果" })
                };
            }
            catch (System.Exception ex)
            {
                // 记录异常日志 (如果配置了日志系统)
                // _logger.LogError(ex, "删除供应商 {SupplierId} 时发生异常", id);
                return StatusCode(500, new { code = -2, message = $"服务器内部错误: {ex.Message}" });
            }
        }


        /// <summary>
        /// 修改供应商
        /// </summary>
        /// <param name="updateSupplierDto"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> UpdateSupplier(UpdateSupplierDto updateSupplierDto)
        {
            return await supplierService.UpdateSupplier(updateSupplierDto);
        }

        /// <summary>
        /// 修改状态
        /// </summary>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> UpdateStatus(int sup_id, int sup_status)
        {
            return await supplierService.UpdateStatus(sup_id, sup_status);
        }

        /// <summary>
        /// 查询部门
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<Department>> GetDepartment(int? Department_id)
        {
            return await supplierService.GetDepartment(Department_id);
        }

        /// <summary>
        /// 查询用户
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<User>> GetUser(int? Department_id)
        {
            return await supplierService.GetUser(Department_id);
        }

        /// <summary>
        /// 查询字典
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<DictData>> GetDictData(int dict_id)
        {
            return await supplierService.GetDictData(dict_id);
        }

        /// <summary>
        /// Id查供应商
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<Supplier> GetIdSupplier(int id)
        {
            return await supplierService.GetIdSupplier(id);
        }

        /// <summary>
        /// 高级查询功能
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public Task<FenYe<Supplier>> GetSeniorSupplier(int CurrentPage, string? sup_code, string? sup_name, string? sup_industry, string? sup_type, string? sup_linkman, string? sup_linkphone, string? sup_email, string? sup_depName, string? sup_userName, int? sup_status, string? sup_address, string? sup_accountName, string? sup_taxpayerNum, string? sup_bankAccount, string? sup_openBank, string? create_name, string? startTime, string? endTime)
        {
            FenYe<Supplier> fenYe = new FenYe<Supplier>()
            {
                CurrentPage = CurrentPage,
            };
            return supplierService.GetSeniorSupplier(fenYe, sup_code, sup_name, sup_industry, sup_type, sup_linkman, sup_linkphone, sup_email, sup_depName, sup_userName, sup_status, sup_address, sup_accountName, sup_taxpayerNum, sup_bankAccount, sup_openBank, create_name, startTime, endTime);
        }

        /// <summary>
        /// 导入供应商
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ImportSupplier()
        {
            var file = HttpContext.Request.Form.Files["file"];
            if (file == null || file.Length == 0)
                return BadRequest(new { message = "未上传文件" });

            try
            {
                // 获取现有供应商编号 (优化: 使用 HashSet 提高查找效率)
                // 注意: GetSupplierID() 方法已在 Repository 中修正了表名
                var existingCodesList = await supplierService.GetSupplierID();
                var existingCodes = new HashSet<string>(existingCodesList); // 转换为 HashSet

                using var stream = new MemoryStream();
                await file.CopyToAsync(stream);

                using var package = new ExcelPackage(stream);
                var worksheet = package.Workbook.Worksheets[0];

                if (worksheet.Dimension == null)
                    return BadRequest(new { message = "Excel文件没有数据" });

                int rowCount = worksheet.Dimension.Rows;
                int colCount = worksheet.Dimension.Columns;

                // 读取表头
                var headers = Enumerable.Range(1, colCount)
                    .Select(col => worksheet.Cells[1, col].Value?.ToString()?.Trim())
                    .ToList();

                // 验证必要列
                var requiredColumns = new List<string> { "供应商编码", "供应商" };
                var missingColumns = requiredColumns.Where(c => !headers.Contains(c)).ToList();
                if (missingColumns.Any())
                    return BadRequest(new { message = $"Excel缺少必要列: {string.Join(", ", missingColumns)}" });

                var successCount = 0;
                var errorMessages = new List<string>();

                // 从第二行开始读取数据
                for (int row = 2; row <= rowCount; row++)
                {
                    var supplierDto = new AddSupplierDto();
                    bool hasError = false;

                    for (int col = 1; col <= colCount; col++)
                    {
                        var header = headers[col - 1];
                        var value = worksheet.Cells[row, col].Value?.ToString()?.Trim();

                        try
                        {
                            // 特殊处理int类型字段
                            if (header == "进货部门id" || header == "进货负责人id" || header == "状态")
                            {
                                if (!string.IsNullOrEmpty(value))
                                {
                                    if (int.TryParse(value, out int intValue))
                                    {
                                        switch (header)
                                        {
                                            case "进货部门id":
                                                supplierDto.sup_depId = intValue;
                                                break;
                                            case "进货负责人id":
                                                supplierDto.sup_userId = intValue;
                                                break;
                                            case "状态":
                                                supplierDto.sup_status = intValue;
                                                break;
                                        }
                                    }
                                    else
                                    {
                                        errorMessages.Add($"第{row}行[{header}]列值'{value}'不是有效的整数");
                                        hasError = true;
                                        break;
                                    }
                                }
                                // 如果值为空字符串，则不设置该 int 属性，保持默认值 0 或 null (如果属性是 int?)
                            }
                            else
                            {
                                // 处理其他字符串字段
                                switch (header)
                                {
                                    case "供应商编码":
                                        supplierDto.sup_code = value;
                                        break;
                                    case "供应商":
                                        supplierDto.sup_name = value;
                                        break;
                                    case "所属行业":
                                        supplierDto.sup_industry = value;
                                        break;
                                    case "供应商分类":
                                        supplierDto.sup_type = value;
                                        break;
                                    case "联系人":
                                        supplierDto.sup_linkman = value;
                                        break;
                                    case "联系电话":
                                        supplierDto.sup_linkphone = value;
                                        break;
                                    case "电子邮箱":
                                        supplierDto.sup_email = value;
                                        break;
                                    case "进货部门":
                                        supplierDto.sup_depName = value;
                                        break;
                                    case "进货负责人":
                                        supplierDto.sup_userName = value;
                                        break;
                                    case "供应商地址":
                                        supplierDto.sup_address = value;
                                        break;
                                    case "备注":
                                        supplierDto.remark = value;
                                        break;
                                    case "账户名称":
                                        supplierDto.sup_accountName = value;
                                        break;
                                    case "纳税人识别号":
                                        supplierDto.sup_taxpayerNum = value;
                                        break;
                                    case "银行账户":
                                        supplierDto.sup_bankAccount = value;
                                        break;
                                    case "开户银行":
                                        supplierDto.sup_openBank = value;
                                        break;
                                    case "开户行地址":
                                        supplierDto.sup_openBankAddress = value;
                                        break;
                                    case "创建人":
                                        supplierDto.create_name = value;
                                        break;
                                    // 注意：创建时间通常由数据库生成 (GETDATE())，这里导入可能不需要或需要特殊处理
                                    case "创建时间":
                                        supplierDto.create_time = value; // 如果需要导入创建时间，确保格式正确
                                        break;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            errorMessages.Add($"第{row}行[{header}]列处理错误: {ex.Message}");
                            hasError = true;
                            break;
                        }
                    }

                    // 跳过错误行
                    if (hasError) continue;

                    // 验证必要字段
                    if (string.IsNullOrEmpty(supplierDto.sup_code))
                    {
                        errorMessages.Add($"第{row}行错误: 供应商编码不能为空");
                        continue;
                    }

                    // 检查重复 (使用 HashSet.Contains，效率高)
                    if (existingCodes.Contains(supplierDto.sup_code))
                    {
                        errorMessages.Add($"第{row}行错误: 供应商编码 {supplierDto.sup_code} 已存在");
                        continue;
                    }

                    // 添加供应商
                    var result = await supplierService.AddSupplier(supplierDto);
                    if (result == 1)
                    {
                        successCount++;
                        // 更新内存中的 HashSet，防止后续行导入相同编码导致重复
                        existingCodes.Add(supplierDto.sup_code);
                    }
                    else
                    {
                        errorMessages.Add($"第{row}行导入失败: 服务返回错误代码 {result}");
                    }
                }

                return Ok(new
                {
                    successCount,
                    errorCount = errorMessages.Count,
                    errors = errorMessages
                });
            }
            catch (Exception ex)
            {
                // 记录异常日志 (如果配置了日志系统)
                // _logger.LogError(ex, "导入供应商时发生异常");
                return StatusCode(500, new { message = "处理文件时出错", error = ex.Message, stackTrace = ex.StackTrace });
            }
        }



        /// <summary>
        /// 查询所有供应商
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<Supplier>> GetAllSupplier()
        {
            return await supplierService.GetAllSupplier();
        }
    }
}
